package nbcp.model

import nbcp.base.comm.Require
import org.apache.commons.codec.digest.DigestUtils

import nbcp.base.extend.*
import nbcp.base.utils.CodeUtil
import nbcp.base.utils.HttpUtil
import nbcp.base.utils.Md5Util
import nbcp.base.utils.MyUtil
import nbcp.service.WeiXinPayUtil
import java.lang.Exception
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

//微信支付，获取预支付Id
data class WxPayParameterData(
        @Require
        var appid: String, //	是

        @Require
        var mch_id: String,//是

        @Require
        var notify_url: String,//是

        @Require
        var body: String,       // 商品描述

        @Require
        var out_trade_no: String,//是

        @Require
        var total_fee: Int //是

) {
    @Require
    private var nonce_str: String = CodeUtil.getCode().Slice(0, 32)  //是
    @Require
    private var spbill_create_ip = ""   // 终端IP

    private var sign_type: String = "MD5" //否
    private var fee_type: String = "CNY" //否
    private var time_start: String = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) //否
    private var time_expire: String = LocalDateTime.now().plusMinutes(30).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) //否
    private var limit_pay: String = "no_credit" // 指定支付方式

    @Require
    var trade_type: String = "APP" //是 , APP , JSAPI 两种
    var device_info: String = "WEB" //否
    var detail = ""; // 商品详情
    var attach: String = "" // 附加数据
    var goods_tag: String = "" // 订单优惠标记

//    var     receipt:Char = 'N'

    //App端支付
    fun toAppPayXml(AppSecret: String):String{
        this.trade_type = "APP"
        return toXml(AppSecret);
    }

    //微信小程序端支付
    fun toWxAppPayXml(AppSecret: String):String{
        this.trade_type = "JSAPI"
        return toXml(AppSecret);
    }

    private fun toXml(AppSecret: String): String {
        var sign = WeiXinPayUtil.sign(AppSecret,this );
        if (sign.isEmpty()) return "";

        var type = this::class.java;

        return "<xml>" + type.declaredFields
                .map {
                    var value = it.get(this)
                    if (value is String && value.isNullOrEmpty()) {
                        return@map "" to ""
                    }

                    if (value is Number && value.toInt() == 0) {
                        return@map "" to ""
                    }

                    return@map it.name to value
                }
                .filter { it.first.isNotEmpty() }
                .sortedBy { it.first }
                .toMutableList()
                .apply {
                    this.add("sign" to sign)
                }
                .map {
                    return@map "<${it.first}><![CDATA[${it.second}]]></${it.first}>"
                }
                .joinToString("") + "</xml>";
    }


    fun getPrepayId(AppSecret: String):String{
        val url = HttpUtil("https://api.mch.weixin.qq.com/pay/unifiedorder")
        url.requestHeader["Content-Type"] = "text/xml;charset=UTF-8"
        val result = url.doPost(this.toAppPayXml(AppSecret)).Xml2Json()

        if (result["return_code"] != "SUCCESS" && result["result_code"] != "SUCCESS") {
            throw Exception("获取PrepayId错误:" + result.getStringValue( "return_msg").AsString(result.getStringValue("err_code_des")) );
        }

        return  result["prepay_id"] ?: ""
    }

    //App呼起微信支付需要的数据
    fun getAppPaySignData(partnerid:String,AppSecret: String): WxPaySignData{
        var prepayId = getPrepayId(AppSecret);
        if( prepayId.isEmpty()) {
            throw Exception("获取PrepayId失败！")
        }

        var  ret = WxPaySignData(appid,partnerid, prepayId);
        ret.`package` = "Sign=WXPay";
        ret.sign  = WeiXinPayUtil.sign(AppSecret,ret,"sign");
        return ret;
    }

}


//data class WeiXinGoodDetail(var goods_id :String , var quantity:Int ,var price:Int){
//    var goods_name:String = ""       //商品的实际名称
//    var wxpay_goods_id:String? = null    //微信侧商品编码	,微信支付定义的统一商品编号
//}
//
//data class WeiXinGoodInfo(var goods_detail:WeiXinGoodDetail){
//    var cost_price:Int? = null    // 订单原价
//    var receipt_id:String = "" //小票Id
//}